package com.grm.sys.service.impl;

import com.grm.common.exception.BusinessException;
import com.grm.sys.mapper.SysRoleMapper;
import com.grm.sys.mapper.SysRolePermMapper;
import com.grm.sys.mapper.SysUserMapper;
import com.grm.sys.mapper.SysUserRoleMapper;
import com.grm.sys.model.SysRole;
import com.grm.sys.request.role.SysRoleAddParam;
import com.grm.sys.request.role.SysRoleQueryParam;
import com.grm.sys.request.role.SysRoleUpdateParam;
import com.grm.sys.service.SysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class SysRoleServiceImpl implements SysRoleService {
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysRolePermMapper sysRolePermMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    @Override
    public List<SysRole> queryAll() {
        return sysRoleMapper.queryAll();
    }

    @Override
    public List<SysRole> queryListSelective(SysRoleQueryParam queryParam) {
        return sysRoleMapper.querySelective(queryParam);
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
    @Override
    public void add(SysRoleAddParam sysRoleAddParam) {
        SysRole dbSysRole = sysRoleMapper.queryByCode(sysRoleAddParam.getCode());
        if (dbSysRole != null) {
            throw new BusinessException("角色编码已存在，请重新设置角色编码！");
        }

        SysRole sysRole = sysRoleAddParamToSysRole(sysRoleAddParam);
        sysRoleMapper.insert(sysRole);

        // 添加角色、权限关系
        if (ObjectUtils.isNotEmpty(sysRoleAddParam.getPermIds())) {
            sysRolePermMapper.batchInsert(sysRole.getId(), sysRoleAddParam.getPermIds());
        }
    }

    private SysRole sysRoleAddParamToSysRole(SysRoleAddParam sysRoleAddParam) {
        SysRole sysRole = new SysRole();
        sysRole.setCode(sysRoleAddParam.getCode());
        sysRole.setName(sysRoleAddParam.getName());
        sysRole.setRemark(sysRoleAddParam.getRemark());
        sysRole.setDataScope(sysRoleAddParam.getDataScope());
        return sysRole;
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
    @Override
    public void update(SysRoleUpdateParam sysRoleUpdateParam) {
        SysRole dbSysRole = sysRoleMapper.queryById(sysRoleUpdateParam.getId());
        if (dbSysRole == null) {
            throw new BusinessException("角色不存在！");
        }
        SysRole dbSysRole2 = sysRoleMapper.queryByCode(sysRoleUpdateParam.getCode());
        if (dbSysRole2 != null && !sysRoleUpdateParam.getId().equals(dbSysRole2.getId())) {
            throw new BusinessException("修改后的角色名已被别人使用！");
        }
        SysRole sysRole = sysRoleUpdateParamToSysRole(sysRoleUpdateParam);
        sysRoleMapper.update(sysRole);

        // 更新角色权限关系
        List<Long> newPermIds = sysRoleUpdateParam.getPermIds();
        List<Long> existingPermIds = sysRolePermMapper.queryPermIdsByRoleId(sysRole.getId());

        // 移除不再分配的权限
        List<Long> permsToRemove = new ArrayList<>(existingPermIds);
        permsToRemove.removeAll(newPermIds);
        if (!permsToRemove.isEmpty()) {
            sysRolePermMapper.deleteByRoleIdAndPermIds(sysRole.getId(), permsToRemove);
        }

        // 添加新权限
        List<Long> permsToAdd = new ArrayList<>(newPermIds);
        permsToAdd.removeAll(existingPermIds);
        if (ObjectUtils.isNotEmpty(permsToAdd)) {
            sysRolePermMapper.batchInsert(sysRole.getId(), permsToAdd);
        }
    }

    private SysRole sysRoleUpdateParamToSysRole(SysRoleUpdateParam sysRoleUpdateParam) {
        SysRole sysRole = new SysRole();
        sysRole.setId(sysRoleUpdateParam.getId());
        sysRole.setCode(sysRoleUpdateParam.getCode());
        sysRole.setName(sysRoleUpdateParam.getName());
        sysRole.setRemark(sysRoleUpdateParam.getRemark());
        sysRole.setDataScope(sysRoleUpdateParam.getDataScope());
        return sysRole;
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)
    @Override
    public void delete(List<Long> ids) {
        if (ObjectUtils.isEmpty(ids)) {
            return;
        }
        // 删除角色表中的数据
        sysRoleMapper.deleteByIds(ids);
        // 删除用户-角色关联表中的数据
        sysUserRoleMapper.deleteByRoleIds(ids);
        // 删除角色-权限关联表中的数据
        sysRolePermMapper.deleteByRoleIds(ids);
    }
}
